home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / auctex / font-latex.el.z / font-latex.el
Encoding:
Text File  |  1998-05-21  |  45.1 KB  |  1,053 lines

  1. ;;; font-latex.el --- LaTeX fontification for Font Lock mode.
  2.  
  3. ;; Copyright (C) 1996, 1997, 1998 Peter S. Galbraith
  4.  
  5. ;; Authors:    Peter S. Galbraith <galbraith@mixing.qc.dfo.ca>
  6. ;;             Simon Marshall <Simon.Marshall@esrin.esa.it>
  7. ;; Maintainer: Peter S. Galbraith <galbraith@mixing.qc.dfo.ca>
  8. ;; Created:    06 July 1996
  9. ;; Version:    0.509 (06 Feb 98)
  10. ;; Keywords:   LaTeX faces
  11.  
  12. ;; RCS $Id: font-latex.el,v 1.53 1998/02/06 15:53:44 rhogee Exp $
  13. ;; Note: RCS version number does not correspond to release number.
  14.  
  15. ;; LCD Archive Entry: (Not yet submitted!)
  16. ;; font-latex|Peter Galbraith|galbraith@mixing.qc.dfo.ca|
  17. ;; LaTeX fontification for font-lock|
  18. ;; 06-Jul-1996|0.01|~/modes/font-latex.el|
  19.  
  20. ;; The archive is archive.cis.ohio-state.edu in /pub/gnu/emacs/elisp-archive.
  21.  
  22. ;;; This file is not part of GNU Emacs.
  23.  
  24. ;; This package is free software; you can redistribute it and/or modify
  25. ;; it under the terms of the GNU General Public License as published by
  26. ;; the Free Software Foundation; either version 2, or (at your option)
  27. ;; any later version.
  28.  
  29. ;; This package is distributed in the hope that it will be useful,
  30. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  31. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  32. ;; GNU General Public License for more details.
  33.  
  34. ;; You should have received a copy of the GNU General Public License
  35. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  36. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  37. ;; Boston, MA 02111-1307, USA.
  38.  
  39. ;;; Commentary:
  40. ;;  This package enhances font-lock fontification patterns for LaTeX.
  41.  
  42. ;; New versions of this package (if they exist) may be found at:
  43. ;;  ftp://ftp.phys.ocean.dal.ca/users/rhogee/elisp/font-latex.el
  44.  
  45. ;; Description:
  46. ;;  This package enhances font-lock fontification patterns for LaTeX.
  47. ;;  font-lock mode is a minor mode that causes your comments to be
  48. ;;  displayed in one face, strings in another, reserved words in another,
  49. ;;  and so on.
  50. ;;
  51. ;;  Please see the accompanying file font-latex.tex for a demo of what
  52. ;;  font-latex is supposed to do at different fontification levels.
  53.  
  54. ;; Installation instructions:
  55. ;;
  56. ;;  Put this file in your emacs load-path, and byte-compile it:
  57. ;;    M-x byte-compile-file
  58. ;;  ** It runs faster when you byte-compile it! **
  59. ;;
  60. ;;  Then all you need to do is add this form to your .emacs file:
  61. ;;
  62. ;;    (if window-system
  63. ;;        (require 'font-latex))
  64. ;;
  65. ;; Turning on font-latex:
  66. ;;
  67. ;;   After font-latex is loaded (or `required'), it will be automatically
  68. ;;   used whenever you enter `font-lock-mode' on a LaTeX buffer. Therefore,
  69. ;;   I direct you to the file font-lock.el that comes with Emacs for more
  70. ;;   info.
  71. ;;
  72. ;; Turning on Font-lock automatically:
  73. ;;
  74. ;;  If you choose to turn-on font-lock by default using a mode-hook,
  75. ;;  there is an order to respect with-respect-to loading font-latex.  
  76. ;;  Do either:
  77. ;;
  78. ;;    (if window-system
  79. ;;        (progn
  80. ;;          (require 'font-latex)
  81. ;;          (add-hook 'latex-mode-hook 'turn-on-font-lock 'append)
  82. ;;          (add-hook 'LaTeX-mode-hook 'turn-on-font-lock 'append)))
  83. ;;  or
  84. ;;    (if window-system
  85. ;;        (progn
  86. ;;          (add-hook 'latex-mode-hook 'turn-on-font-lock)
  87. ;;          (add-hook 'LaTeX-mode-hook 'turn-on-font-lock)
  88. ;;          (require 'font-latex)))
  89. ;;
  90. ;;  It's probably not a bad idea to always append 'turn-on-font-lock
  91. ;;  such that it is always sure to be last.
  92. ;;
  93. ;; Fontification Levels:
  94. ;;
  95. ;;  There are two levels of fontification, selected by the value of the
  96. ;;  font-lock variable font-lock-maximum-decoration.  There are ways
  97. ;;  documented in font-latex.el to set this differently for each mode that
  98. ;;  uses font-lock, but if you are unsure and are running on a fast enough
  99. ;;  machine, try putting this in your ~/.emacs file: 
  100. ;;    (setq font-lock-maximum-decoration t) 
  101. ;;  It probably best to put it before the (require 'font-latex) statement.
  102. ;;
  103. ;; Changing colours
  104. ;;
  105. ;;  Okay, so you hate the colours I picked.  How do you change them you ask?
  106. ;;  First, find the font name to change using the command:
  107. ;;    M-x list-text-properties-at
  108. ;;  Then, suppose you got `font-latex-math-face', edit ~/.Xdefaults and add:
  109. ;;    Emacs.font-latex-math-face.attributeForeground: blue
  110. ;;  without the semi-colon I'm using here ascomment delimiters, of course.
  111. ;;
  112. ;; Lazy-lock users:
  113. ;;
  114. ;;  lazy-lock and font-latex don't work too well together (up to Emacs 19.33
  115. ;;  and XEmacs 19.14 anyway).  font-latex uses functions to find text to
  116. ;;  fontify that may span more than one line, and this doesn't suit
  117. ;;  lazy-lock's search limits too well.  Recent versions of font-latex are
  118. ;;  a bit better, and perhaps you can live with the occasional 
  119. ;;  mis-fontification.
  120. ;;
  121. ;; Old hilit19 (and hilit-LaTeX) users:
  122. ;;
  123. ;;  If you are upgrading from using hilit-LaTeX.el or were using hilit19,
  124. ;;  you must disable hilit19 (at least for latex mode) in order to use
  125. ;;  font-latex.el.  Here's how:
  126. ;;  
  127. ;;  - If you don't care to use hilit19 at all, don't `load' or `require' it 
  128. ;;    in your ~/.emacs file by removing the "(require 'hilit-LaTeX)" line.
  129. ;;  - If you wish to use hilit19 everywhere but in latex mode, add the 
  130. ;;    following before your `load' or `require' hilit19:
  131. ;;
  132. ;;    (setq hilit-mode-enable-list  '(not latex-mode))
  133. ;;
  134. ;;  You can tell you are using font-latex instead of hilit-LaTeX because:
  135. ;;
  136. ;;  - colours will be different 
  137. ;;  - You'll see a message like `Fontifying font-latex.tex...done' 
  138. ;;    instead of `highlighting 1: \(^\|[^\\]\)\(\\[a-zA-Z\\]+\)'
  139. ;; ----------------------------------------------------------------------------
  140. ;;; Change log:
  141. ;; V0.509 20Feb98 PSG (RCS V1.53)
  142. ;;    XEmacs infinite loop in font-latex-match-font-inside-braces cache.
  143. ;; V0.508 06Feb98 PSG (RCS V1.51)
  144. ;;    Created font-latex-match-textual; changed font-latex-math-face colour.
  145. ;; V0.507 30Jan98 PSG (RCS V1.50)
  146. ;;    Removed font-latex-find-matching-close because it broke the cache.
  147. ;;    Rewrote the cache method.  Ouch!
  148. ;; V0.506 08Jan98 PSG (RCS V1.48)
  149. ;;    Added variables font-latex-match-variable, font-latex-match-function
  150. ;;    font-latex-match-reference (built using reexp-opt).
  151. ;; V0.505 07Jan98 PSG (RCS V1.47)
  152. ;;    XEmacs20 has defface.
  153. ;; V0.504 20Oct97 Kevin Ruland <kruland@seistl.com> (RCS V1.46)
  154. ;;    Fixed the real bug in font-latex-match-command-outside-arguments
  155. ;; V0.503 16Oct97 PSG (RCS V1.45)
  156. ;;    Patched font-latex-match-command-outside-arguments for allow for
  157. ;;    strange interaction with AUC-TeX's LaTeX-environment command.
  158. ;; V0.502 07Oct97 (RCS V1.44)
  159. ;;    Kevin Ruland <kevin@rodin.wustl.edu> edits font-latex-find-matching-close
  160. ;;    PSG: Changed OliveGreen for OliveDrab, found in rgb.txt
  161. ;; V0.501 24Sep97 (RCS V1.42)
  162. ;;    Kevin Ruland <kevin@rodin.wustl.edu> added font-latex-find-matching-close
  163. ;;    used instead of scan-sexp to find arguments containing extra brackets.
  164. ;; V0.500 23Sep97 PSG (RCS V1.41)
  165. ;;  - Support for Emacs-20 (No customize support yet)
  166. ;; V0.403 19Nov96 (RCS V1.37)
  167. ;;  - Christoph Wedler <wedler@fmi.uni-passau.de>
  168. ;;    XEmacs patch for local math-font 
  169. ;;  - Changed scheme for fontification of \section*{...}  
  170. ;; V0.402 13Nov96 PSG (RCS V1.35)
  171. ;;  - Embeded comments handled.
  172. ;;  - Better XEmacs initilisation.
  173. ;; V0.401 12Nov96 PSG (RCS V1.34) - Nothing fontified when commented-out. 
  174. ;; V0.400 11Nov96 PSG (RCS V1.33) 
  175. ;;  - Stab at on-the-fly multiline.
  176. ;;  - mono support: <Johannes.Weinert@Informatik.Uni-Oldenburg.DE>
  177. ;; V0.314 16Oct96 PSG - Support for dark background removed for XEmacs.
  178. ;; V0.313 07Oct96 PSG (RCS V1.31) - Support for dark background.
  179. ;; V0.312 26Aug96 PSG (RCS V1.30) - Added font-latex-commented-outp.
  180. ;; V0.311 22Aug96 PSG (RCS V1.29) - fixed for XEmacs.
  181. ;; V0.310 22Aug96 simon (RCS V1.27)
  182. ;;  - make font-latex-setup run font-lock-make-faces before variable trickery.
  183. ;;  - set font-latex-string-face to the global value of font-lock-string-face.
  184. ;; V0.309 21Aug96 PSG (RCS V1.26)
  185. ;;  - new font-latex-math-face done by string syntax.  User may modify it.
  186. ;;  - new font-latex-string-face.
  187. ;; V0.308 15Aug96 PSG (RCS V1.25) 
  188. ;;  - $$...$$ gets font-latex-math-face
  189. ;;  - font-latex-match-math-envII fixed.
  190. ;; V0.307 14Aug96 PSG (RCS V1.23) - setup okay if loaded in a latex-mode-hook
  191. ;; V0.306 14Aug96 PSG (RCS V1.22) - added "item" to font-latex-match-function
  192. ;; V0.305 14Aug96 PSG (RCS V1.20) - use keep in font-latex-match-math-envII
  193. ;; V0.304 14Aug96 PSG (RCS V1.18) - minor comment edits.
  194. ;; V0.303 14Aug96 simon (RCS V1.17)
  195. ;;  - rewrote font-latex-match-math-envII like font-latex-match-quotation
  196. ;; V0.302 12Aug96 PSG (RCS V1.16)
  197. ;;  - (goto-char end) in condition-case error to avoid infinite loops.
  198. ;; V0.301 08Aug96 PSG (RCS V1.14)
  199. ;;  - Better faces in XEmacs.
  200. ;; V0.300 07Aug96 PSG (RCS V1.12)
  201. ;;  - Changed font-latex-match-font-inside-braces again for stranded \bf
  202. ;;  - "[a-z]+box" changed
  203. ;;  - font-latex-match-math-env checks preceding-char for \\[
  204. ;;  - use eval-after-compile in font-latex-match-math-envII 
  205. ;; V0.201 05Aug96 PSG added \\(display\\)?math to Simon's changes 
  206. ;; V0.200 05Aug96 simon: (RCS V1.10)
  207. ;;  - fixed font-latex-match-command-outside-arguments
  208. ;;  - rewrote font-latex-match-font-outside-braces like above
  209. ;;  - rewrote font-latex-match-font-inside-braces like above
  210. ;; V0.101 01Aug96 PSG added \\(display\\)?math
  211. ;; V0.100 01Aug96 PSG - massive new test version
  212. ;; V0.061 23Jul96 PSG
  213. ;;  - Removed trailing "\\>" in warning-face regexp (fails with \\ \- \\*)
  214. ;; V0.06  23Jul96 PSG
  215. ;;  - fixed dobib in font-latex-labels.
  216. ;;  - shorter font regexp in levels 3+4.
  217. ;;  - removed \item and & from type
  218. ;;  - fixed font-latex-math-envII regexp
  219. ;; V0.05  22Jul96 PSG
  220. ;;  - changed \ref etc to reference-face.
  221. ;;  - \\b added in buggy \item[option] regexp (not really fixed).
  222. ;;  - font-latex-labels regexp bug
  223. ;; V0.041  simon:
  224. ;;  - added font-latex-match-command-outside-arguments
  225. ;;  - rewrote font-latex-match-quotation and font-latex-bib-highlight-mouse
  226. ;;  - rewrote then removed bib-cite functionality.
  227. ;;  - general top-level cleanup
  228. ;; V0.04 11Jul96 PSG
  229. ;;  - added font-lock-comment-start-regexp defined in 19.32
  230. ;;  - encoded 8-bit characters to 7-bit.
  231. ;; V0.03 10Jul96 PSG
  232. ;;  - font-latex-bib-cite-mouse-highlight-p can change after font-lock-defaults
  233. ;;    is constructed.
  234. ;; V0.02 09Jul96 PSG 
  235. ;;  - added font-latex-bib-cite-mouse-highlight-p
  236. ;;  - Fixed `overwrite' flags
  237. ;; V0.01 06Jul96 Peter S Galbraith - Created
  238. ;; ----------------------------------------------------------------------------
  239. ;;; Code:
  240. (require 'font-lock)
  241.  
  242. (defvar font-latex-warning-face            'font-latex-warning-face
  243.   "Face to use for LaTeX major keywords.")
  244. (defvar font-latex-sedate-face            'font-latex-sedate-face
  245.   "Face to use for LaTeX minor keywords.")
  246. (defvar font-latex-italic-face            'font-latex-italic-face
  247.   "Face to use for LaTeX italics.")
  248. (defvar font-latex-bold-face            'font-latex-bold-face
  249.   "Face to use for LaTeX bolds.")
  250. (defvar font-latex-math-face            'font-latex-math-face
  251.   "Face to use for LaTeX math environments.")
  252.  
  253. (defvar font-latex-match-variable
  254.   (concat 
  255.    "\\\\" "\\("
  256. ;;;(regexp-opt
  257. ;;; '("setlength" "settowidth" "setcounter" "addtolength" "addtocounter"))
  258.    "addto\\(counter\\|length\\)\\|set\\(counter\\|length\\|towidth\\)"
  259.    "\\)\\>")
  260.   "font-latex regexp to match LaTeX variable keywords.")
  261.  
  262. (defvar font-latex-match-reference
  263.   (concat 
  264.    "\\\\" "\\("
  265. ;;;(regexp-opt
  266. ;;; '("nocite" "cite" "label" "pageref" "vref" "eqref" "ref"
  267. ;;;   "include" "input" "bibliography"
  268. ;;;   "index" "glossary" "footnote" "footnotemark" "footnotetext"))
  269.    "bibliography\\|cite[a-zA-Z]*\\|eqref\\|footnote\\(mark\\|text\\)?\\|"
  270.    "glossary\\|in\\(clude\\|dex\\|put\\)\\|label\\|nocite\\|pageref\\|ref\\|"
  271.    "vref"
  272.    "\\)\\>")
  273.   "font-latex regexp to match reference keywords.")
  274.   
  275. (defvar font-latex-match-function
  276.   (concat 
  277.    "\\\\" "\\("
  278. ;;;(regexp-opt
  279. ;;; '("begin" "end"
  280. ;;;   "pagenumbering"
  281. ;;;   "thispagestyle" "pagestyle"
  282. ;;;   "nofiles" "includeonly"
  283. ;;;   "bibliographystyle" "documentstyle" "documentclass"
  284. ;;;   "newenvironment" "newcommand" "newlength" "newtheorem" "newcounter"
  285. ;;;   "renewenvironment" "renewcommand" "renewlength" "renewtheorem" 
  286. ;;;   "renewcounter"
  287. ;;;   "usepackage" "fbox" "mbox" "sbox" "vspace" "hspace"))
  288.    "b\\(egin\\|ibliographystyle\\)\\|document\\(class\\|style\\)\\|"
  289.    "end\\|fbox\\|hspace\\|includeonly\\|mbox\\|"
  290.    "n\\(ew\\(co\\(mmand\\|unter\\)\\|environment\\|length\\|theorem\\)"
  291.        "\\|ofiles\\)\\|"
  292.     "page\\(numbering\\|style\\)\\|"
  293.     "renew\\(co\\(mmand\\|unter\\)\\|environment\\|length\\|theorem\\)\\|"
  294.     "sbox\\|thispagestyle\\|usepackage\\|vspace"
  295.    "\\)\\>")
  296.   "font-latex regexp to match LaTeX function keywords.")
  297.  
  298. (defvar font-latex-match-textual
  299.   (concat 
  300.    "\\\\" "\\("
  301. ;;;(regexp-opt
  302. ;;; '("item" ;;;FIXME: does not have an {arg} so should treated elsewhere.
  303. ;;;   "part" "chapter" "section" "subsection" "subsubsection" 
  304. ;;;   "paragraph" "subparagraph" "subsubparagraph" 
  305. ;;;   "title" "author" "date" "thanks" "address"
  306. ;;;   "caption"))
  307.    "a\\(ddress\\|uthor\\)\\|c\\(aption\\|hapter\\)\\|date\\|item\\|"
  308.    "par\\(agraph\\|t\\)\\|"
  309.    "s\\(ection\\|"
  310.        "ub\\(paragraph\\|s\\(ection\\|ub\\(paragraph\\|section\\)\\)\\)\\)\\|"
  311.    "t\\(hanks\\|itle\\)"
  312.    "\\)\\>")
  313.   "font-latex regexp to match LaTeX function with text arguemnt.")
  314.  
  315.  
  316. (defvar font-latex-keywords-1
  317.   (list
  318.    ;; FIXME: Maybe I should put this in a function, use override but let
  319.    ;;        the function determine if commented-out.
  320.    (list (concat 
  321.           "\\\\" "\\("
  322. ;;; (regexp-opt
  323. ;;;  '("nopagebreak" "pagebreak" "newpage" "clearpage" "cleardoublepage"
  324. ;;;    "enlargethispage" "nolinebreak" "linebreak" "newline"
  325. ;;;    "-" "\\" "\\*" "displaybreak" "allowdisplaybreaks"))
  326.           "\\\\\\*\\|allowdisplaybreaks\\|clear\\(doublepage\\|page\\)\\|"
  327.           "displaybreak\\|enlargethispage\\|linebreak\\|"
  328.           "n\\(ew\\(line\\|page\\)\\|o\\(linebreak\\|pagebreak\\)\\)\\|"
  329.           "pagebreak\\|[\\-]"
  330.           
  331.           "\\)")
  332.      '(0 font-latex-warning-face))
  333.    '("\\$\\$\\([^$]+\\)\\$\\$" 1 font-latex-math-face)        ;;; $$...$$
  334.    '(font-latex-match-quotation . font-latex-string-face)     ;;; ``...''
  335.    '(font-latex-match-font-outside-braces              ;;;\textit{text}
  336.      (0 font-lock-keyword-face
  337.         append                         ;Override? [t 'keep 'prepend 'append]
  338.         ;; Can't use prepend because that overwrites syntax fontification
  339.         ;; e.g. comments.
  340.         t)                              ;Laxmatch? if t, do not signal error
  341.      (1 font-latex-italic-face append t)
  342.      (2 font-latex-bold-face append t)
  343.      (3 font-lock-type-face append t))
  344.    '(font-latex-match-font-inside-braces              ;;;{\it text}
  345.      (0 font-lock-keyword-face append t)
  346.      (1 font-latex-italic-face append t)
  347.      (2 font-latex-bold-face append t)
  348.      (3 font-lock-type-face append t)))
  349.   "Subdued level highlighting for LaTeX modes.")
  350.  
  351. (defvar font-latex-keywords-2
  352.   (append font-latex-keywords-1
  353.    '((font-latex-match-reference                              ;;;\cite
  354.       (0 font-lock-keyword-face append t)
  355.       (1 font-lock-variable-name-face append t)              ;;;    [opt]
  356.       (2 font-lock-reference-face append t))                 ;;;         {key}
  357.      (font-latex-match-function                               ;;;\documentclass
  358.       (0 font-lock-keyword-face append t)
  359.       (1 font-lock-variable-name-face append t)              ;;;   [opt]
  360.       (2 font-lock-function-name-face append t))             ;;;        {text}
  361.      (font-latex-match-textual                               ;;;\section
  362.       (0 font-lock-keyword-face append t)
  363.       (1 font-lock-variable-name-face append t)              ;;;   [opt]
  364.       (2 font-lock-type-face append t))                      ;;;        {text}
  365.      (font-latex-match-variable
  366.       (0 font-lock-keyword-face nil t)
  367.       (1 font-lock-variable-name-face append t)
  368.       (2 font-lock-variable-name-face append t))
  369.      (font-latex-match-math-env 
  370.       (0 font-latex-math-face append t))                   ;;;\(...\)
  371.      (font-latex-match-math-envII                             ;;;Math environ.
  372.       (0 font-latex-math-face append t))
  373.      ("\\\\[@A-Za-z]+"                                        ;;;Other commands
  374.       (0 font-latex-sedate-face append))))
  375.   "High level highlighting for LaTeX modes.")
  376.  
  377. (defvar font-latex-keywords font-latex-keywords-1
  378.   "Default expressions to highlight in TeX mode.")
  379.  
  380. ;; End-User can stop reading here.
  381.  
  382. ;; Make sure font-latex.el is supported.  I don't claim to have tested this...
  383. (if (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version)))
  384.     (and (= emacs-major-version 19) (< emacs-minor-version 14))
  385.       (and (= emacs-major-version 19) (< emacs-minor-version 29)))
  386.     (error "`font-latex' was written for Emacs 19.29/XEmacs 19.14 or later"))
  387.  
  388. (defvar font-latex-is-XEmacs19
  389.   (and (not (null (save-match-data 
  390.                     (string-match "XEmacs\\|Lucid" emacs-version))))
  391.        (= 19 emacs-major-version)))
  392. (defvar font-latex-is-XEmacs20
  393.   (and (not (null (save-match-data 
  394.                     (string-match "XEmacs\\|Lucid" emacs-version))))
  395.        (= 20 emacs-major-version)))
  396. (defvar font-latex-is-Emacs19
  397.   (and (not font-latex-is-XEmacs19) 
  398.        (not font-latex-is-XEmacs20) 
  399.        (= 19 emacs-major-version)))
  400. (defvar font-latex-is-Emacs20
  401.   (and (not font-latex-is-XEmacs19) 
  402.        (not font-latex-is-XEmacs20) 
  403.        (= 20 emacs-major-version)))
  404.  
  405. (defvar font-latex-string-face nil
  406.   "Face to use for strings.  This is set by Font LaTeX.")
  407.  
  408. (defvar font-lock-comment-start-regexp nil
  409.   "Regexp to match the start of a comment.")
  410.  
  411. (eval-when-compile
  412.   (require 'cl))
  413.  
  414. (cond
  415.  ((or font-latex-is-Emacs20 
  416.       font-latex-is-XEmacs20)
  417.   (defface font-latex-bold-face
  418.     '((((class grayscale) (background light)) (:foreground "DimGray" :bold t))
  419.       (((class grayscale) (background dark)) (:foreground "LightGray" :bold t))
  420.       (((class color) (background light)) 
  421.        (:foreground "DarkOliveGreen" :bold t ))
  422.       (((class color) (background dark)) (:foreground "OliveDrab" :bold t ))
  423.       (t (:bold t)))
  424.     "Font Lock mode face used to bold LaTeX."
  425.     :group 'font-latex-highlighting-faces)
  426.   
  427.   (defface font-latex-italic-face
  428.     '((((class grayscale) (background light)) 
  429.        (:foreground "DimGray" :italic t))
  430.       (((class grayscale) (background dark)) 
  431.        (:foreground "LightGray" :italic t))
  432.       (((class color) (background light)) 
  433.        (:foreground "DarkOliveGreen" :italic t ))
  434.       (((class color) (background dark)) 
  435.        (:foreground "OliveDrab" :italic t ))
  436.       (t (:italic t)))
  437.     "Font Lock mode face used to highlight italic LaTeX."
  438.     :group 'font-latex-highlighting-faces)
  439.  
  440.   (defface font-latex-math-face
  441.     '((((class grayscale) (background light)) 
  442.        (:foreground "DimGray" :underline t))
  443.       (((class grayscale) (background dark)) 
  444.        (:foreground "LightGray" :underline t))
  445.       (((class color) (background light)) (:foreground "SaddleBrown"))
  446.       (((class color) (background dark))  (:foreground "burlywood"))
  447.       (t (:underline t)))
  448.     "Font Lock mode face used to highlight math in LaTeX."
  449.     :group 'font-latex-highlighting-faces)
  450.  
  451.   (defface font-latex-sedate-face
  452.     '((((class grayscale) (background light)) (:foreground "DimGray"))
  453.       (((class grayscale) (background dark))  (:foreground "LightGray"))
  454.       (((class color) (background light)) (:foreground "DimGray"))
  455.       (((class color) (background dark))  (:foreground "LightGray"))
  456.    ;;;(t (:underline t))
  457.       )
  458.     "Font Lock mode face used to highlight sedate stuff in LaTeX."
  459.     :group 'font-latex-highlighting-faces)
  460.  
  461.   (copy-face 'font-lock-string-face 'font-latex-string-face)
  462.   (if font-latex-is-Emacs20
  463.       (copy-face 'font-lock-warning-face 'font-latex-warning-face)
  464.     (defface font-latex-warning-face
  465.       '((((class grayscale)(background light))(:foreground "DimGray" :bold t))
  466.         (((class grayscale)(background dark))(:foreground "LightGray" :bold t))
  467.         (((class color)(background light))(:foreground "red" :bold t ))
  468.         (((class color)(background dark))(:foreground "red" :bold t ))
  469.         (t (:bold t)))
  470.       "Font Lock for LaTeX major keywords."
  471.       :group 'font-latex-highlighting-faces)))
  472.  (font-latex-is-Emacs19
  473.   (if (not font-lock-face-attributes)
  474.       ;; Otherwise I overwrite fock-lock-face-attributes.
  475.       (font-lock-make-faces))
  476.   (unless (assq 'font-latex-sedate-face font-lock-face-attributes)
  477.     (cond 
  478.      ;; FIXME: Add better conditions for grayscale.
  479.      ((memq font-lock-display-type '(mono monochrome grayscale greyscale
  480.                                      grayshade greyshade))
  481.       (setq font-lock-face-attributes
  482.             (append 
  483.              font-lock-face-attributes
  484.              (list '(font-latex-bold-face nil nil t nil nil)
  485.                    '(font-latex-italic-face nil nil nil t nil)
  486.                    '(font-latex-math-face nil nil nil nil t)
  487.                    '(font-latex-sedate-face nil nil nil t nil)
  488.                    (list
  489.                     'font-latex-warning-face
  490.                     (cdr (assq 'background-color (frame-parameters)))
  491.                     (cdr (assq 'foreground-color (frame-parameters)))
  492.                     nil nil nil)))))
  493.      ((eq font-lock-background-mode 'light) ; light colour background
  494.       (setq font-lock-face-attributes
  495.            (append 
  496.             font-lock-face-attributes
  497.                  ;;;FIXME: These won't follow font-lock-type-face's changes.
  498.                  ;;;       Should I change to a (copy-face) scheme?
  499.             '((font-latex-bold-face "DarkOliveGreen" nil t nil nil)
  500.               (font-latex-italic-face "DarkOliveGreen" nil nil t nil)
  501.               (font-latex-math-face "SaddleBrown")
  502.               (font-latex-sedate-face "grey50")
  503.               (font-latex-warning-face "red" nil t nil nil)))))
  504.     (t            ; dark colour background
  505.      (setq font-lock-face-attributes
  506.            (append 
  507.             font-lock-face-attributes
  508.             '((font-latex-bold-face "OliveDrab" nil t nil nil)
  509.               (font-latex-italic-face "OliveDrab" nil nil t nil)
  510.               (font-latex-math-face "burlywood")
  511.           ;; good are > LightSeaGreen, LightCoral, coral, orchid, orange
  512.               (font-latex-sedate-face "grey60")
  513.               (font-latex-warning-face "red" nil t nil nil))))))))
  514.  (t
  515.   ;;; XEmacs19:
  516.   (make-face 'font-latex-string-face "Face to use for LaTeX string.")
  517.   (copy-face 'font-lock-string-face 'font-latex-string-face)
  518.  
  519.   (make-face 'font-latex-bold-face "Face to use for LaTeX bolds.")
  520.   (copy-face 'font-lock-type-face 'font-latex-bold-face)
  521.   (make-face-bold 'font-latex-bold-face)
  522.  
  523.   (make-face 'font-latex-italic-face "Face to use for LaTeX italics.")
  524.   (copy-face 'font-lock-type-face 'font-latex-italic-face)
  525.   (make-face-italic 'font-latex-italic-face)
  526.  
  527.   (make-face 'font-latex-math-face "Face to use for LaTeX math.")
  528.   (make-face 'font-latex-sedate-face "Face to use for LaTeX minor keywords.")
  529.   (make-face 'font-latex-warning-face "Face to use for LaTeX major keywords.")
  530.   (make-face-bold 'font-latex-warning-face)
  531.   ;; XEmacs uses a tag-list thingy to determine if we are using color
  532.   ;;  or mono (and I assume a dark background).
  533.   (set-face-foreground 'font-latex-math-face "green4" 'global nil 'append)
  534.   (set-face-foreground 'font-latex-sedate-face "grey50" 'global nil 'append)
  535.   (set-face-foreground 'font-latex-warning-face "red" 'global nil 'append)))
  536.  
  537. (defun font-latex-setup ()
  538.   "Setup this buffer for LaTeX font-lock.  Usually called from a hook."
  539.   ;; Trickery to make $$ fontification be in `font-latex-math-face' while
  540.   ;; strings get whatever `font-lock-string-face' has been set to.
  541.   (cond
  542.    (font-latex-is-Emacs20
  543.     (make-local-variable 'font-lock-string-face)
  544.     (setq font-lock-string-face font-latex-math-face
  545.       font-latex-string-face (default-value 'font-lock-string-face))
  546.     ;; Tell Font Lock about the support.
  547.     (make-local-variable 'font-lock-defaults)
  548.     ;; Parentheses () disabled because they should not delimit fontification
  549.     ;; in LaTeX text.
  550.     (setq font-lock-defaults
  551.       '((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2)
  552.         nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
  553.         (font-lock-comment-start-regexp . "%")
  554.         (font-lock-mark-block-function . mark-paragraph))))
  555.    ((or font-latex-is-XEmacs19 font-latex-is-XEmacs20)
  556.     ;; Cool patch from Christoph Wedler...
  557.     (let (instance)
  558.       (mapcar (function
  559.            (lambda (property)
  560.          (setq instance
  561.                (face-property-instance 'font-latex-math-face property
  562.                            nil 0 t))
  563.          (if (numberp instance)
  564.              (setq instance
  565.                (face-property-instance 'default property nil 0)))
  566.          (or (numberp instance)
  567.              (set-face-property 'font-lock-string-face property
  568.                     instance (current-buffer)))))
  569.           (built-in-face-specifiers))))
  570.    (t
  571.     (font-lock-make-faces)
  572.     (make-local-variable 'font-lock-string-face)
  573.     (setq font-lock-string-face font-latex-math-face
  574.       font-latex-string-face (default-value 'font-lock-string-face))
  575.     ;; Tell Font Lock about the support.
  576.     (make-local-variable 'font-lock-defaults)
  577.     ;; Parentheses () disabled because they should not delimit fontification
  578.     ;; in LaTeX text.
  579.     (setq font-lock-defaults
  580.       '((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2)
  581.         nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
  582.         (font-lock-comment-start-regexp . "%")
  583.         (font-lock-mark-block-function . mark-paragraph))))))
  584.  
  585. (when (or font-latex-is-XEmacs19 font-latex-is-XEmacs20)
  586.     (put 'latex-mode 'font-lock-defaults
  587.          '((font-latex-keywords font-latex-keywords-1 font-latex-keywords-2)
  588.            nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
  589.            (font-lock-comment-start-regexp . "%")
  590.            (font-lock-mark-block-function . mark-paragraph)))
  591.     (put 'latex-tex-mode    'font-lock-defaults 'latex-mode)
  592.     (put 'LaTex-tex-mode    'font-lock-defaults 'latex-mode)
  593.     (put 'LaTeX-mode        'font-lock-defaults 'latex-mode)
  594.     (put 'japanese-LaTeX-mode 'font-lock-defaults 'latex-mode)
  595.     (put 'LATeX-MoDe    'font-lock-defaults 'latex-mode)
  596.     (put 'lATEx-mODe    'font-lock-defaults 'latex-mode))
  597.  
  598.  
  599. (defun font-latex-match-reference (limit)
  600.   (if font-latex-match-reference
  601.       (font-latex-match-command-outside-arguments font-latex-match-reference
  602. ;;;   (eval-when-compile
  603. ;;;     (concat "\\\\" "\\("
  604. ;;;             (mapconcat 'identity 
  605. ;;;              '("[A-Za-z]*cite[A-Za-z]*" "label" "\\(page\\|v\\|eq\\)?ref"
  606. ;;;                "index" "glossary" "\\(footnote\\(mark\\|text\\)?\\)")
  607. ;;;              "\\|")
  608. ;;;      "\\)\\>"))
  609.                                                   limit nil nil)))
  610.  
  611. (defun font-latex-match-function (limit)
  612.   "Fontify things like \\documentclass{article}"
  613.   (if font-latex-match-function
  614.       (font-latex-match-command-outside-arguments font-latex-match-function
  615.                                                   limit nil t)))
  616. (defun font-latex-match-textual (limit)
  617.   "Fontify things like \\section{text}"
  618.   (if font-latex-match-textual
  619.       (font-latex-match-command-outside-arguments font-latex-match-textual
  620.                                                   limit nil t)))
  621. (defun font-latex-match-variable (limit)
  622.   "Fontify things like \\newcommand{stuff}"
  623.   (if font-latex-match-variable
  624.       (font-latex-match-command-outside-arguments font-latex-match-variable
  625.                                                   limit t nil)))
  626.  
  627. ;; font-latex-find-matching-close is a little helper function which
  628. ;; is used like scan-sexp.  It skips over matching
  629. ;; pairs of '{' and '}'.  As an added benefit, it ignores any characters
  630. ;; which occur after the tex comment character %.
  631. (defun font-latex-find-matching-close (closechar)
  632. "*Skip over matching pairs of '{' and '}', ignoring
  633. any characters in comments, until closechar is found.  If the end of file
  634. is reached, return nil."
  635.   (save-excursion
  636.     (save-match-data
  637.       (let ((mycount 1))
  638.     (while (and (> mycount 0)
  639.             (progn
  640.               (backward-char 1)
  641.               (re-search-forward
  642.                (concat "[^\\\\]["
  643.                    ;; closechar might be ]
  644.                    ;; and therefor must be first in regexp
  645.                    (char-to-string closechar)
  646.                    "{}%]")
  647.                nil t)))
  648.       (if (= (preceding-char) ?%) ;; Found a comment
  649.           (forward-line 1)
  650.         (setq mycount (if (= (preceding-char) ?{)
  651.                   (+ mycount 1)
  652.                 (- mycount 1)))))
  653.     (if (= mycount 0)
  654.             (point)
  655.           (error ""))))))
  656.  
  657. ;; FIXME: --About font-latex-commented-outp--
  658. ;; Fontification is *slower* for affected functions (in particular
  659. ;; font-latex-match-function), so it will be worth it to increase
  660. ;; performance in the algorithm.
  661. ;;  - don't return (store-match-data (list nil nil)) in
  662. ;;    font-latex-match-command-outside-arguments, instead skip over
  663. ;;    commented-out parts internally.  
  664. ;;  - Perhaps handling outlined code is excessive and slows down the 
  665. ;;    search too much?
  666. ;;  - Is save-match-data expensive? The calling function could store
  667. ;;    the match-data before it calls (font-latex-commented-outp) knowing
  668. ;;    that is would trash the list.
  669. (defun font-latex-commented-outp ()
  670.   "Return t is comment character is found between bol and point."
  671.   (save-excursion
  672.     (let ((limit (point)))
  673.       (save-match-data
  674.         ;; Handle outlined code
  675.         (re-search-backward "^\\|\C-m" (point-min) t)
  676.         (if (re-search-forward "^%\\|[^\\]%" limit t)
  677.             t
  678.           nil)))))
  679.  
  680. (defvar font-latex-match-command-cache-start nil
  681.   "Cache start of unterminated match to fontify")
  682. (defvar font-latex-match-command-cache-end nil
  683.   "Cache end of unterminated match to fontify")
  684. (defvar font-latex-match-command-cache-limit nil
  685.   "Cache limit of unterminated match to fontify")
  686. (defvar font-latex-match-command-cache-keywords nil
  687.   "Cache keywords of unterminated match to fontify")
  688. (defvar font-latex-match-command-cache-match nil
  689.   "Cache last match of unterminated match")
  690. (defvar font-latex-match-command-cache-stop nil
  691.   "Flag to not move point, because same pattern was returned twice to fontify")
  692.  
  693. (make-variable-buffer-local 'font-latex-match-command-cache-start)
  694. (make-variable-buffer-local 'font-latex-match-command-cache-end)
  695. (make-variable-buffer-local 'font-latex-match-command-cache-limit)
  696. (make-variable-buffer-local 'font-latex-match-command-cache-keywords)
  697. (make-variable-buffer-local 'font-latex-match-command-cache-match)
  698. (make-variable-buffer-local 'font-latex-match-command-cache-stop)
  699.  
  700. ;; FIXME - Note to myself 
  701. ;; In call to font-latex-match-command-outside-arguments, I could arrange
  702. ;; such that keywords which cannot use [options] have this set to nil.
  703. ;; LaTeX code woulldn't fontify if options are used illegally in commands,
  704. ;; cuing users in that they are doing something wrong.  (See RCS V1.11 for
  705. ;; useopt option)
  706. ;;
  707. ;; NOTE - Without an override flag, font-lock does not re-fontify the
  708. ;;  option `opt' when the `t' is typed-in in "\cite[opt".  The first `o'
  709. ;;  was fontified and now has a face, which font-lock-apply-highlight
  710. ;;  won't override.  The `p' and `t' get a face as they are typed by 
  711. ;;  inheriting from left-stickyness on the `o'.
  712. ;;  THEREFORE, I cannot rely on font-lock-apply-highlight to continue 
  713. ;;  multi-line incomplete patterns, because the first character of the 
  714. ;;  pattern on the first line has a face.  I must use `prepend'.
  715. (defun font-latex-match-command-outside-arguments (keywords limit twoargs 
  716.                                                    asterix)
  717.   "Search for regexp command KEYWORDS[opt]{arg} before LIMIT.
  718. If TWOARG is t, allow two arguments {arg1}{arg2}
  719. If ASTERIX is t, fontify trailing asterix in command.
  720. Sets `match-data' so that:
  721.  subexpression 0 is the keyword, 
  722.  subexpression 1 is the contents of any following [...] forms 
  723.  subexpression 2 is the contents of any following {...} forms.  
  724. Returns nil if none of KEYWORDS is found."
  725.   (when (and font-latex-match-command-cache-keywords
  726.              font-latex-match-command-cache-limit
  727.              font-latex-match-command-cache-start
  728.              font-latex-match-command-cache-end
  729.              (equal font-latex-match-command-cache-keywords keywords)
  730.              (< font-latex-match-command-cache-start (point))
  731.              (not (= font-latex-match-command-cache-end (point)))
  732.              (> font-latex-match-command-cache-limit (point))
  733.              (not font-latex-match-command-cache-stop))
  734.     (goto-char font-latex-match-command-cache-start))
  735.   (setq font-latex-match-command-cache-stop nil)
  736.   (when (re-search-forward keywords limit t)
  737.     (cond
  738.      ((font-latex-commented-outp)
  739.       ;; Return a nul match such that we skip over this pattern.
  740.       ;; (Would be better to skip over internally to this function)
  741.       (store-match-data (list nil nil))
  742.       t)
  743.      (t
  744.       (let ((kbeg (match-beginning 0)) 
  745.             kend sbeg send cbeg cend
  746.             cache-reset
  747.             (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
  748.         (goto-char (match-end 0))
  749.         (if (and asterix (eq (following-char) ?\*))
  750.             (forward-char 1)) 
  751.         (skip-chars-forward " \n\t" limit)
  752.         (setq kend (point))
  753.         (while (eq (following-char) ?\[)
  754.           (setq sbeg kend)
  755.           (save-restriction
  756.             ;; Restrict to LIMIT.
  757.             (narrow-to-region (point-min) limit)
  758.             (if (condition-case nil
  759.                     (goto-char (or (scan-sexps (point) 1)
  760.                                 ;;;(font-latex-find-matching-close ?\])
  761.                                    (point-max)))
  762.                   (error))
  763.                 (setq send (point))
  764.               (setq cache-reset t)
  765.               (setq send (point-max))
  766.               (goto-char send))))
  767.         (skip-chars-forward " \n\t" limit)
  768.         (when (eq (following-char) ?\{)
  769.           (setq cbeg (point))
  770.           (save-restriction
  771.             ;; Restrict to LIMIT.
  772.             (narrow-to-region (point-min) limit)
  773.             (if (condition-case nil
  774.                     (goto-char (or (scan-sexps (point) 1) (point-max)))
  775.                   (error))
  776.                 (setq cend (point))
  777.               (setq cache-reset t)
  778.               (setq cend (point-max))
  779.               (goto-char cend)))
  780.           (when twoargs
  781.             (skip-chars-forward " \n\t" limit)
  782.             (when (eq (following-char) ?\{)
  783.               (save-restriction
  784.                 ;; Restrict to LIMIT.
  785.                 (narrow-to-region (point-min) limit)
  786.                 (if (condition-case nil
  787.                         (goto-char (or (scan-sexps (point) 1) (point-max)))
  788.                       (error))
  789.                     (setq cend (point))
  790.                   (setq cache-reset t)
  791.                   (setq cend (point-max))
  792.                   (goto-char cend))))))
  793.         (store-match-data (list kbeg kend sbeg send cbeg cend))
  794.  
  795.         (when (and font-latex-match-command-cache-keywords ;Sanity check!
  796.                    (equal font-latex-match-command-cache-keywords keywords)
  797.                    font-latex-match-command-cache-match
  798.                    (equal font-latex-match-command-cache-match
  799.                           (list kbeg kend sbeg send cbeg cend)))
  800.           (setq font-latex-match-command-cache-stop t))
  801.         (setq font-latex-match-command-cache-match
  802.               (list kbeg kend sbeg send cbeg cend))
  803.  
  804.         (when cache-reset
  805.           (setq font-latex-match-command-cache-start kbeg
  806.                 font-latex-match-command-cache-end   kend
  807.                 font-latex-match-command-cache-limit (point)
  808.                 font-latex-match-command-cache-keywords keywords))
  809.           t)))))
  810.  
  811. (defvar font-latex-match-font-cache-start nil
  812.   "Cache start of unterminated match to fontify")
  813. (defvar font-latex-match-font-cache-end nil
  814.   "Cache end of unterminated match to fontify")
  815. (defvar font-latex-match-font-cache-limit nil
  816.   "Cache limit of unterminated match to fontify")
  817. (make-variable-buffer-local 'font-latex-match-font-cache-start)
  818. (make-variable-buffer-local 'font-latex-match-font-cache-end)
  819. (make-variable-buffer-local 'font-latex-match-font-cache-limit)
  820.  
  821. (defun font-latex-match-font-outside-braces (limit)
  822.   "Search for font-changing command like \textbf{fubar} before LIMIT.  
  823. Sets `match-data' so that:
  824.  subexpression 0 is the keyword, 
  825.  subexpression 1 is the content to fontify in italic.
  826.  subexpression 2 is the content to fontify in bold.
  827.  subexpression 3 is the content to fontify in type-face.
  828. Returns nil if no font-changing command is found."
  829.   (when (and font-latex-match-font-cache-limit
  830.              font-latex-match-font-cache-start
  831.              font-latex-match-font-cache-end
  832.              (not (= font-latex-match-font-cache-end (point)))
  833.              (> font-latex-match-font-cache-limit (point))
  834.              (< font-latex-match-font-cache-start (point)))
  835.     (goto-char font-latex-match-font-cache-start))
  836.   (when (re-search-forward
  837.          (eval-when-compile
  838.            (concat "\\\\" "\\("
  839.                    "\\(emph\\)\\|"                  ;;; 2 - italic
  840.                    "\\(text\\("
  841.                                "\\(it\\|sl\\)\\|"          ;;; 5 - italic
  842.                                "\\(md\\|rm\\|sf\\|tt\\)\\|"   ;;; 6 - type
  843.                                "\\(bf\\|sc\\|up\\)"          ;;; 7 - bold
  844.                           "\\)\\)\\|"
  845.                    "\\(boldsymbol\\|pmb\\)"              ;;; 8 - bold
  846.                    "\\)" "{"))
  847.          limit t)
  848.     (cond
  849.      ((font-latex-commented-outp)
  850.       ;; Return a nul match such that we skip over this pattern.
  851.       ;; (Would be better to skip over internally to this function)
  852.       ;; Using `prepend' won't help here, because the problem is that
  853.       ;; scan-sexp *fails* to find a commented-out matching bracket!
  854.       (store-match-data (list nil nil))
  855.       t)
  856.      (t
  857.       (let ((kbeg (match-beginning 0)) (kend (match-end 1)) 
  858.             (beg  (match-end 0)) 
  859.             end itbeg itend bfbeg bfend ttbeg ttend
  860.             (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
  861.         (goto-char kend)
  862.         (save-restriction
  863.           ;; Restrict to LIMIT.
  864.           (narrow-to-region (point-min) limit)
  865.           (cond 
  866.            ((condition-case nil
  867.                 (goto-char (or (scan-sexps (point) 1)
  868.                               ;;;(font-latex-find-matching-close ?\})
  869.                                (point-max)))
  870.               (error))
  871.             (setq end (1- (point))))
  872.            (t
  873.             (setq end (point-max))
  874.             (goto-char end)
  875.             (setq font-latex-match-font-cache-start kbeg
  876.                   font-latex-match-font-cache-end   kend
  877.                   font-latex-match-font-cache-limit (point)))))
  878.         (cond ((or (match-beginning 2) (match-beginning 5))
  879.                (setq itbeg beg  itend end))
  880.               ((match-beginning 6)
  881.                (setq ttbeg beg  ttend end))
  882.               (t
  883.                (setq bfbeg beg  bfend end)))
  884.         (store-match-data 
  885.          (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
  886.         ;; Start the subsequent search immediately after this keyword.
  887.         (goto-char kend)
  888.         t)))))
  889.  
  890. (defvar font-latex-match-infont-cache-start nil
  891.   "Cache start of unterminated match to fontify")
  892. (defvar font-latex-match-infont-cache-end nil
  893.   "Cache end of unterminated match to fontify")
  894. (defvar font-latex-match-infont-cache-limit nil
  895.   "Cache end of unterminated match to fontify")
  896. (make-variable-buffer-local 'font-latex-match-infont-cache-start)
  897. (make-variable-buffer-local 'font-latex-match-infont-cache-end)
  898. (make-variable-buffer-local 'font-latex-match-infont-cache-limit)
  899.  
  900. (defun font-latex-match-font-inside-braces (limit)
  901.   "Search for font-changing command like {\bf fubar} before LIMIT.  
  902. Sets `match-data' so that:
  903.  subexpression 0 is the keyword. 
  904.  subexpression 1 is the content to fontify in italic.
  905.  subexpression 2 is the content to fontify in bold.
  906.  subexpression 3 is the content to fontify in type-face.
  907. Returns nil if no font-changing command is found."
  908.   (when (and font-latex-match-infont-cache-limit
  909.              font-latex-match-infont-cache-start
  910.              font-latex-match-infont-cache-end
  911.              (not (= font-latex-match-infont-cache-end (point)))
  912.              (> font-latex-match-infont-cache-limit (point))
  913.              (<  font-latex-match-infont-cache-start (point)))
  914.     (goto-char font-latex-match-infont-cache-start))
  915.   (when (re-search-forward
  916.          (eval-when-compile
  917.            (concat "\\\\" "\\("
  918.                                                               ;;; 2 - italic
  919.                    "\\(em\\|it\\(shape\\)?\\|sl\\(shape\\)?\\)\\|"
  920.                                                           ;;; 5 - bold
  921.                    "\\(bf\\(series\\)?\\|upshape\\|sc\\(shape\\)?\\)\\|"
  922.                    "mdseries\\|tt\\(family\\)?\\|"
  923.                    "sf\\(family\\)?\\|rm\\(family\\)?\\|"
  924.                    "tiny\\|scriptsize\\|footnotesize\\|"
  925.                    "small\\|normalsize\\|large\\|Large\\|LARGE\\|huge\\|Huge"
  926.                    "\\)\\>[ \t]*"))
  927.          limit t)
  928.     (cond
  929.      ((font-latex-commented-outp)
  930.       ;; Return a nul match such that we skip over this pattern.
  931.       ;; (Would be better to skip over internally to this function)
  932.       ;; Using `prepend' won't help here, because the problem is that
  933.       ;; scan-sexp *fails* to find a commented-out matching bracket!
  934.       (store-match-data (list nil nil))
  935.       t)
  936.      (t
  937.       (let ((kbeg (match-beginning 0)) (kend (match-end 1)) 
  938.             (beg  (match-end 0))
  939.             end itbeg itend bfbeg bfend ttbeg ttend
  940.             (parse-sexp-ignore-comments t)) ; scan-sexps ignores comments
  941.         (goto-char kbeg)
  942.         (cond 
  943.          ((not (eq (preceding-char) ?\{))
  944.           ;; Fontify only the keyword as bf/it/type (no argument found).
  945.           (cond ((match-beginning 2) (setq itbeg kbeg itend kend))
  946.                 ((match-beginning 5) (setq bfbeg kbeg bfend kend))
  947.                 (t                   (setq ttbeg kbeg ttend kend)))
  948.           (goto-char (match-end 0))
  949.           (store-match-data 
  950.            (list nil nil itbeg itend bfbeg bfend ttbeg ttend))
  951.           t)
  952.          (t
  953.           ;; There's an opening bracket
  954.           (save-restriction
  955.             ;; Restrict to LIMIT.
  956.             (narrow-to-region (point-min) limit)
  957.             (forward-char -1)           ;Move on the opening bracket
  958.             (cond 
  959.              ((condition-case nil
  960.                   (goto-char (or (scan-sexps (point) 1) (point-max)))
  961.                 (error))
  962.               (setq end (point)))
  963.              (t                         ;error!
  964.               (setq end (point-max))
  965.               (goto-char end)
  966.               (setq font-latex-match-infont-cache-start kbeg
  967.                     font-latex-match-infont-cache-end   kend
  968.                     font-latex-match-infont-cache-limit (point))))
  969.             (cond ((match-beginning 2) (setq itbeg beg  itend end))
  970.                   ((match-beginning 5) (setq bfbeg beg  bfend end))
  971.                   (t                   (setq ttbeg beg  ttend end)))
  972.             (store-match-data 
  973.              (list kbeg kend itbeg itend bfbeg bfend ttbeg ttend))
  974.             ;; Start the subsequent search immediately after this keyword.
  975.             (goto-char kend)
  976.             t))))))))
  977.  
  978. ;;; FIXME: Add caches for math-env, math-envII and quotations.
  979. (defun font-latex-match-math-env (limit)
  980.   "Used for patterns like:
  981. \\( F = ma \\)
  982. \\ [ F = ma \\] but not \\\\ [len]"
  983.   (when (re-search-forward "\\(\\\\(\\)\\|\\(\\\\\\[\\)" limit t)
  984.     (goto-char (match-beginning 0))
  985.     (if (eq (preceding-char) ?\\)       ; \\[ is not a math environment
  986.         (progn 
  987.           (goto-char (match-end 0))
  988.           (store-match-data (list nil nil)) 
  989.           t)
  990.       (let ((b1start (point)))
  991.         (search-forward (cond ((match-beginning 1) "\\)")
  992.                               (t                   "\\]"))
  993.                         limit 'move)
  994.         (let ((b2end (or (match-end 0) (point))))
  995.           (store-match-data (list b1start b2end))
  996.           t)))))
  997.  
  998. (defun font-latex-match-math-envII (limit)
  999.   "Used for patterns like:
  1000. \\begin{equation}
  1001.  fontified stuff
  1002. \\end{equation}
  1003. The \\begin{equation} and \\end{equation are not fontified here."
  1004.   (when (re-search-forward 
  1005.          (eval-when-compile 
  1006.            (concat "\\\\begin{\\(\\(display\\)?math\\|equation\\|eqnarray"
  1007.                    "\\|gather\\|multline\\|align\\|x*alignat"
  1008.                    "\\)\\*?}"))
  1009.          limit t)
  1010.     (let ((beg (match-end 0)) end)
  1011.       (if (search-forward (concat "\\end{" (buffer-substring 
  1012.                                             (match-beginning 1)(match-end 0)))
  1013.                           limit 'move)
  1014.           (setq end (match-beginning 0))
  1015.         (setq end (point)))
  1016.       (store-match-data (list beg end))
  1017.       t)))
  1018.  
  1019. (defun font-latex-match-quotation (limit)
  1020.   "Used for patterns like:
  1021. ``this is a normal quote'' and these are multilingual quoted strings:
  1022. \"< french \"> and \"`german\"' quotes, << french >> and 8-bit french."
  1023.   (when (re-search-forward
  1024.      (eval-when-compile
  1025.        (concat "\\(``\\)\\|\\(\"<\\)\\|\\(\"`\\)\\|\\(<<\\)\\|"
  1026.            "\\(" (char-to-string 171) "\\)")) ; An 8-bit "<<"
  1027.      limit t)
  1028.     (let ((beg (match-beginning 0)))
  1029.       (search-forward
  1030.        (cond ((match-beginning 1) "''")
  1031.          ((match-beginning 2) "\">")
  1032.          ((match-beginning 3) "\"'")
  1033.          ((match-beginning 4) ">>")
  1034.          ((match-beginning 5) (eval-when-compile (char-to-string 187))))
  1035.        limit 'move)
  1036.       (store-match-data (list beg (point)))
  1037.       t)))
  1038.  
  1039. ;; Install ourselves
  1040.  
  1041. (add-hook 'LaTeX-mode-hook 'font-latex-setup)
  1042. (add-hook 'latex-mode-hook 'font-latex-setup)
  1043. ;; If font-latex is loaded using a latex-mode-hook, then the add-hook above
  1044. ;; won't be called this time around.  Check for this now:
  1045. (if (eq major-mode 'latex-mode)
  1046.     (font-latex-setup))
  1047.  
  1048. ;; Provide ourselves:
  1049.  
  1050. (provide 'font-latex)
  1051.  
  1052. ;;; font-latex.el ends here
  1053.